package com.ks.servlet;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ks.entity.OnlineUser;
import com.ks.entity.User;
import com.ks.listener.UserSessionListener;
import com.ks.service.UserService;
import com.ks.utils.CookieUtils;
import com.ks.utils.Factory;

import common.Var;

/**
 * 用户登录请求的Servlet,登录成功后将用户信息存在session中;实现单一登录
 * 
 * @author 47475
 *
 */
@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
	private static Logger log = LoggerFactory.getLogger(LoginServlet.class);
	private static final long serialVersionUID = 1L;
	UserService userServiceImpl = (UserService) Factory.getBean("userServiceImpl");

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		String remember = req.getParameter("rememberMe");
//		
//		  log.debug("URL"+req.getRequestURL().toString());
//		  log.debug("URI"+req.getRequestURI());
//		  log.debug("ContextPath:"+req.getContextPath());
//		  log.debug("ServletPath:"+req.getServletPath());
//		  log.debug("ServletContext:"+req.getServletContext());
//		  log.debug("getPathInfo:"+req.getPathInfo());
//		  log.debug("getMethod:"+req.getMethod());
//		  log.debug("getHeader(user-agent):"+req.getHeader("user-agent"));
//		  log.debug("RemoteAddr:"+req.getRemoteAddr());
//		  log.debug("RemotePort:"+req.getRemotePort());
//		  log.debug("LocalName:"+req.getLocalName());
//		  log.debug("LocalAddr:"+req.getLocalAddr());
//		  log.debug("RemotePort:"+req.getLocalPort());
//		  log.debug("RequestedSessionId:"+req.getRequestedSessionId());
////		  log.debug("RemoteAddr:"+req.changeSessionId());
//		  log.debug("getProtocol:"+req.getProtocol());
		 
		User user = userServiceImpl.getUserById(username);
		// 0->用户不存在 1->登陆成功 2—>密码错误
		int ret = 0;
		if (user != null) {
			// 用户名正确
			if (user.getPassword().equals(password)) {
				// 密码正确
				HttpSession session = req.getSession(true);
//				log.info("上一次访问时间：【{}】" ,new Date(session.getLastAccessedTime()));
				/** 设置session保存时间一小时 */
//				session.setMaxInactiveInterval(3600);
				/** 用户选择记住密码，设置cookie保存时间一小时，一小时内免登录 */
				if ("true".equals(remember)) {
					CookieUtils.addCookie(req, resp, Var.USERNAME, username, 3600,false);
					CookieUtils.addCookie(req, resp, Var.PASSWORD, password, 3600,false);
				} else {
					// 不记住密码删除客户端Cookie,不删除session
					CookieUtils.deleteCookieNow(req, resp, Var.USERNAME, Var.PASSWORD);
				}

				/** 下面代码功能限制一个账号同时只能同时在一个客户端登录 */

				// 获取sessionMap中存的SessionId与客户端传来的SesssionId对比，如果不相同则不是一个客户端登录，清除上一个客户端登录的session信息
				String sessionId = req.getRequestedSessionId();
				log.debug("客户端传来的SessionID【{}】", sessionId);

				HttpSession lastsession = UserSessionListener.sessionMap.get(user.getUsername());

				if (lastsession != null) {
					// 该用户的session已经存在于Map中(同一客户端或者不同客户端)
					log.debug("Mapy已经保存了用户【{}】的Session，SessionID为【{}】,将验证是不是同一个客户端：", username, lastsession.getId());
					if (!lastsession.getId().equals(sessionId)) {
						log.info("用户【{}】不在同一客户端登录，将踢出上一个登录", username);
						// 将新登录用户信息保存到session中
						session.setAttribute(Var.USER_INFO, user);
						forceUserLogout(user.getUsername());
						UserSessionListener.sessionMap.put(user.getUsername(), session);
					} else {
						log.debug("用户【{}】在同一客户端登录", username);
					}

				} else {
					log.debug("Map没有保存该用户的Session,用户【{}】没有登录！！！", username);
					// 将当前用户信息保存到session中
					session.setAttribute(Var.USER_INFO, user);
					// 将当前用户及session保存到唯一登录变量Map中
					UserSessionListener.sessionMap.put(user.getUsername(), session);
				}

//				
//				if (lastsession!=null&&lastsession.getId().equals(sessionId)) {
//					log.debug("用户【{}】在同一客户端重复登录",username);
//				} else {
//					session.setAttribute(Var.USER_INFO, user);
//				}
//				
//				if (lastsession != null) {
//					log.debug("Map保存了该用户的Session，SessionID为【{}】,将验证是不是同一个客户端：", lastsession.getId());
//				}else {
//					session.setAttribute(Var.USER_INFO, user);
//				}
//				if (null != lastsession && !lastsession.getId().equals(sessionId)) {
//					/** 如果该账户已经登录，将已经登陆的信息拿掉,将新的用户登录信息放进去 */
//					log.info("当前用户【{}】已经登录，不是同一客户端登录，将踢出上一个登录", username);
//					forceUserLogout(user.getUsername());
//					UserSessionListener.sessionMap.put(user.getUsername(), session);
//				}
//				/** 该账号未被登陆 */
//				else {
//					log.debug("用户【{}】没有登录或者是同一客户端登录！！！登录成功！！！", username);
//					UserSessionListener.sessionMap.put(user.getUsername(), session);
//				}
				/** 登录成功返回1 */
				ret = 1;
			} else {
				ret = 2;
				log.warn("--用户【{}】尝试登陆,密码错误", username);
			}
		} else {
			log.warn("--用户【{}】尝试登陆,该用户不存在", username);
		}
		/** 返回给JSP页面写法 */
		if (ret == 1) {
			// 重定向，相当于重新访问页面。request不能保存
//			resp.sendRedirect("/jsp/welcome.jsp");
			req.setAttribute(Var.USER_INFO, user);
			Map<String, String> users = OnlineUser.getInstance().getOnlineUser();
			req.getServletContext().setAttribute(Var.ACCESS_USERS, users);
			System.out.println((Map<String, User>) req.getServletContext().getAttribute(Var.ACCESS_USERS));
			req.getRequestDispatcher("/jsp/welcome.jsp").forward(req, resp);
		} else {
			req.setAttribute(Var.EMG, "用户名或密码错误");
			req.getRequestDispatcher("/jsp/login.jsp").forward(req, resp);
//			resp.sendRedirect("/jsp/login.jsp");
		}
		/** 前后端分离返回给ajax写法 */
//		PrintWriter out = resp.getWriter();
//		Map<String, Object> map = new HashMap<String, Object>();
//		map.put("ret", ret);
//		map.put("data", user);
//		JSONObject json = new JSONObject(map);
//		out.print(json);
//		out.flush();
//		out.close();
	}

	/**
	 * 当发现账号已经被人登陆了，就将这个已经登陆上的人的Session从UserSessionListener.java中的HashMap里给拿到，
	 * 并且移除在此HashMap中的记录
	 * 
	 * @param username
	 */
	public static void forceUserLogout(String username) {
		if (UserSessionListener.sessionMap.get(username) != null) {
			// 获取上一个登陆用户的session
			HttpSession session = UserSessionListener.sessionMap.get(username);
			// 从map中移除上一个登陆用户的信息
			UserSessionListener.sessionMap.remove(username);
			// 移除上一个登陆用户session中的所有属性
			Enumeration<String> e = session.getAttributeNames();

			while (e.hasMoreElements()) {
				String sessionName = e.nextElement();
				session.removeAttribute(sessionName);
			}
			session.invalidate();
		}
	}
}
